/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.swe.chums.beans;

import com.swe.chums.dao.UserDao;
import com.swe.chums.dao.exceptions.UserDaoException;
import com.swe.chums.dao.factory.DaoFactory;
import com.swe.chums.dao.model.User;
import com.swe.chums.dao.model.UserPk;
import com.swe.chums.utils.CommonUtils;
import com.swe.chums.utils.UserActivityTypeEnum;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;

/**
 *
 * @author cilingir
 */
@ManagedBean(name = "loginBean")
@SessionScoped
public class LoginBean implements Serializable{

    private static Logger log = Logger.getLogger(LoginBean.class);
    private User user;
    private boolean loggedIn;
    private boolean isAdmin;
    private boolean isUser;
    
    public LoginBean() {
        
    }
    
    /**
     * Check login processes
     *
     * @return
     */
    public String login() {
        log.debug("[LoginBean.login] - started");
        FacesContext context = FacesContext.getCurrentInstance();
        String text;
        
        try {
            if (user.getUsername() != null && !user.getUsername().equals("")) {
                user.setUsername(user.getUsername().trim());
            } else {
                user.setUsername("");
            }
            
            if (user.getPassword() != null && !user.getPassword().equals("")) {
                user.setPassword(user.getPassword().trim());
            } else {
                user.setPassword("");
            }
            
            if (user.getUsername().equals("")) {
                log.error("[LoginBean.login] - username is empty: " + user.getUsername());
                text = "Username can not be empty";
                context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(user.getUsername())) {
                log.error("[LoginBean.login] - username is not in allowed format: " + user.getUsername());
                text = "Username must be alphanumerical";
                context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(user.getUsername(), 40)) {
                log.error("[LoginBean.login] - username is not in allowed length: " + user.getUsername());
                text = "Username must have less than 40 characters";
                context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }

            if (user.getPassword().equals("")) {
                log.error("[LoginBean.login] - password is empty: " + user.getPassword());
                text = "Password can not be empty";
                context.addMessage("form:password", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAlphaNumerical(user.getPassword())) {
                log.error("[LoginBean.login] - password is not in allowed format: " + user.getPassword());
                text = "Password must be alphanumerical";
                context.addMessage("form:password", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            } else if (!CommonUtils.isAllowedLength(user.getPassword(), 40)) {
                log.error("[LoginBean.login] - password is not in allowed length: " + user.getPassword());
                text = "Password must have less than 40 characters";
                context.addMessage("form:password", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
            }
            
            
            if (!(context.getMessageList().size() > 0)) {
                
                UserDao userDao = DaoFactory.createUserDao();
                ArrayList<User> userList = (ArrayList<User>) userDao.findWhereUsernameEquals(user.getUsername());

                // Check if username exists
                if (userList == null || (userList.isEmpty())) {
                    log.error("[LoginBean.login] - username does not exist : " + user.getUsername());
                    text = "Username does not exist";
                    context.addMessage("form:username", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
                    loggedIn = false;
                    return null;
                } else {
                    User dbUser = userList.get(0);
                    String md5pass = CommonUtils.convertMd5(user.getPassword());
                    log.debug("[LoginBean.login] - password entered md5: " + md5pass);

                    // Check if username matches with password
                    if (!dbUser.getPassword().equals(md5pass)) {
                        log.error("[LoginBean.login] - username password does not match, username: " + user.getUsername() + " password: " + user.getPassword());
                        text = "Username and password do not match";
                        context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", text));
                        loggedIn = false;
                        isUser = false;
                        return null;

                    } else {
                        
                        // Set user logged in
                        loggedIn = true;
                        user = dbUser;
                        UserPk userPk = new UserPk(user.getId());
                        if (user.getUserTypeId() == 2) {
                            log.debug("[LoginBean.login] - user is admin: " + user.getUsername());
                            isAdmin = true;
                        } else {
                            isUser = true;
                        }
                        
                        CommonUtils.recordUserAction(user.getId(), UserActivityTypeEnum.LOGIN, 0, null);
                        
                        log.info("[LoginBean.login] -  logged in");
                        return "index.xhtml?faces-redirect=true";
                    }
                }
            } else {
                log.error("[LoginBean.login] - there are errors with the form");
                loggedIn = false;
                return null;
            }
        } catch (NoSuchAlgorithmException ex) {
            log.error("[LoginBean.login] - error while converting string to md5, message is:" + ex.getMessage());
            context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "General error occured with md5"));
            return null;
        } catch (UserDaoException ex) {
            log.error("[LoginBean.login] - error while retrieving values from DB, message is:  " + ex.getMessage());
            context.addMessage("form", new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "DB error occured"));
            return null;
        }
    }

    /**
     * Log out
     *
     * @return
     */
    public String logout() {
        
        log.debug("[LoginBean.logout] started");

        FacesContext facesContext = FacesContext.getCurrentInstance();
        
        LoginBean loginBean = (LoginBean) facesContext.getExternalContext().getSessionMap().get("loginBean");
        log.debug("[LoginBean.login] recording user action logout for user with the id: " + loginBean.getUser().getId());
        
        CommonUtils.recordUserAction(user.getId(), UserActivityTypeEnum.LOGOUT, 0, null);
        
        // Kill session
        HttpSession httpSession = (HttpSession) facesContext.getExternalContext().getSession(false);
        httpSession.invalidate();
        
        loggedIn = false;
        isUser = false;
        isAdmin = false;
        
        log.info("[LoginBean.logout] logged out");
        return "index.xhtml?faces-redirect=true";
    }
    
    
    /*----Getter Setters---- */

    public User getUser() {
        if (user == null) {
            user = new User();
        }
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public boolean isLoggedIn() {
        return loggedIn;
    }

    public void setLoggedIn(boolean loggedIn) {
        this.loggedIn = loggedIn;
    }

    public boolean isIsAdmin() {
        return isAdmin;
    }

    public void setIsAdmin(boolean isAdmin) {
        this.isAdmin = isAdmin;
    }

    public boolean isIsUser() {
        return isUser;
    }

    public void setIsUser(boolean isUser) {
        this.isUser = isUser;
    }
    
    
    
}
